﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;


namespace DebuggableInstallableService
{
    [RunInstaller(true)]
    public partial class WindowsServiceInstaller : Installer
    {
        public WindowsServiceAttribute Configuration { get; set; }

        public WindowsServiceInstaller() : this(typeof(ServiceImplementation))
        {
            InitializeComponent();
        }

        private WindowsServiceInstaller(Type windowsServiceType)
        {
            if (!windowsServiceType.GetInterfaces().ToList().Contains(typeof(IWindowsService)))
            {
                throw new ArgumentException("Type to install must implement IWindowsService", "windowsServiceType");
            }

            var attr = windowsServiceType.GetAttribute<WindowsServiceAttribute>();

            if(attr == null)
            {
                throw new ArgumentException("Type to install must be marked with a WindowsServiceAttribute.",
                                          "windowsServiceType");
            }

            Configuration = attr;
        }

        public static void RunInstall<T>() where T : IWindowsService
        {
            string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;

            using(var ti = new TransactedInstaller())
            {
                ti.Installers.Add(new WindowsServiceInstaller(typeof (T)));
                ti.Context = new InstallContext(null, new []{ path });
                ti.Install(new Hashtable());
            }
        }
    }
}
